﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.AspNetCore.Mvc.Versioning;
using Microsoft.DotNet.PlatformAbstractions;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Reflection;

namespace Web.Extensions
{
    public static partial class SwaggerConfiguration
    {
        public static IServiceCollection SwaggerSetup(this IServiceCollection services)
        {
            services.AddApiVersioning(options =>
            {
                options.ReportApiVersions = true;
                options.DefaultApiVersion = new ApiVersion(1, 0);
                options.ApiVersionReader = ApiVersionReader.Combine(
                    new QueryStringApiVersionReader("api-version"),
                    new HeaderApiVersionReader("api-version"),
                    new MediaTypeApiVersionReader("ver"),
                    new UrlSegmentApiVersionReader());
            }).AddVersionedApiExplorer(options =>
            {
                options.GroupNameFormat = "'v'V";
                options.SubstituteApiVersionInUrl = true;
            });

            services.AddSwaggerGen();
            var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);
            services.AddOptions<SwaggerGenOptions>()
                .Configure<IApiVersionDescriptionProvider>((options, services) =>
                {
                    options.ResolveConflictingActions(description => description.First());
                    foreach (var item in services.ApiVersionDescriptions)
                    {
                        options.SwaggerDoc(item.GroupName, CreateOpenInfoForApiVersion(item));
                    }
                    options.IncludeXmlComments(Path.Combine(basePath, $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"), true);
                });

            return services;
        }

        private static OpenApiInfo CreateOpenInfoForApiVersion(ApiVersionDescription description)
        {
            var info = new OpenApiInfo
            {
                Title = "API Doc",
                Version = description.ApiVersion.ToString(),
                //Description = $"当前文档环境{}"
            };
            if (description.IsDeprecated)
            {
                info.Description += "此版本已弃用";
            }
            return info;
        }

        public static IApplicationBuilder UseSwaggerConfiguration(this IApplicationBuilder app)
        {
            var provider = app.ApplicationServices.GetRequiredService<IApiVersionDescriptionProvider>();
            app.UseSwagger();
            app.UseSwaggerUI(options =>
            {
                foreach (var description in provider.ApiVersionDescriptions)
                {
                    options.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant());
                    options.RoutePrefix = "swagger";
                }
            });
            return app;
        }
    }
}
